/// @file Series.h
/// @author Przemyslaw Plutecki
/// @author Maciej Siczek
#pragma once
#ifndef SERIES_H_
#define SERIES_H_
#include <boost/noncopyable.hpp>
#include <boost/variant/variant.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/serialization/vector.hpp>
#include <vector>
#include <string>
#include <exception>
#include "StorageVisitor.h"
#include "../common/DataType.h"
namespace LightChart {
/**
        @class Series
        @author Maciej Siczek, Przemyslaw Plutecki
        @version 1.0
        @brief Class for data series.

        @see SeriesStorage
    */
typedef boost::variant<double, std::string, int> variant_values;
class Series: public boost::noncopyable {
public:
	Series(const std::string & name = "", DataType type = UNKNOWN);
	void add(variant_values value) throw (boost::bad_get);
        std::vector<double> & get_double_vector() throw (boost::bad_get);
        std::vector<int> & get_int_vector() throw (boost::bad_get);
        std::vector<std::string> & get_string_vector() throw (boost::bad_get);
        const DataType & get_type() const;
        const std::string & get_name() const;
        void set_name(const std::string name);
protected:
	void set_vector_type();
	std::string name;
        boost::variant<std::vector<double>, std::vector<int>,std::vector<std::string>> values;
	DataType type;
private:
	friend class boost::serialization::access;
        template<class Archive> void serialize(Archive & ar, const unsigned int version);
};

inline std::vector<double> & Series::get_double_vector() throw (boost::bad_get) {
    return boost::get<std::vector<double>>(values);
}
inline std::vector<int> & Series::get_int_vector() throw (boost::bad_get) {
    return boost::get<std::vector<int>>(values);
}
inline std::vector<std::string> & Series::get_string_vector() throw (boost::bad_get) {
    return boost::get<std::vector<std::string>>(values);
}
inline const DataType & Series::get_type() const {
    return type;
}
inline const std::string & Series::get_name() const {
    return name;
}
inline void Series::set_name(const std::string name) {
    this->name = name;
}
template<class Archive> inline void Series::serialize(Archive & ar, const unsigned int) {
    ar & name;
    ar & values;
    ar & type;
}
} /* namespace LightChart */
#endif /* SERIES_H_ */
